#!/bin/env python
# -*- coding:utf-8
"""
@author:xingz
@file:demo6.py
@time:2022/05/24
"""
from typing import *
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from random import randint as ri
import random


def getColor():
    color: int
    color1 = ri(16, 255)
    color2 = ri(16, 255)
    color3 = ri(16, 255)
    color1 = hex(color1)
    color2 = hex(color2)
    color3 = hex(color3)
    ans = "#" + color1[2:] + color2[2:] + color3[2:]
    return ans


def randomcolor():
    colorArr = ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
    color = ""
    for i in range(6):
        color += colorArr[random.randint(0, 14)]
    return "#" + color


def cut_rect_by_line(rect: tuple, line: tuple):
    """

    :param rect:
    :param line:
    :return:
    """
    rect_l = []
    rect_r = []
    rect_t = []
    rect_b = []

    if line[0] == 'x':
        if rect[0] < line[1] < rect[2]:
            rect_l = (rect[0], rect[1], line[1], rect[3])
            rect_r = (line[1], rect[1], rect[2], rect[3])
        elif line[1] <= rect[0]:
            rect_r = rect
        elif line[1] >= rect[2]:
            rect_l = rect

    elif line[0] == 'y':
        if rect[1] < line[1] < rect[3]:
            rect_t = (rect[0], line[1], rect[2], rect[3])
            rect_b = (rect[0], rect[1], rect[2], line[1])
        elif line[1] >= rect[3]:
            rect_b = rect
        elif line[1] <= rect[1]:
            rect_t = rect

    ret = {
        't': rect_t,
        'b': rect_b,
        'l': rect_l,
        'r': rect_r
    }
    return ret


def cut_rect_by_rect(rect: tuple, sep_rect) -> Dict:
    line_map = {'t': ('y', sep_rect[3]),
                'b': ('y', sep_rect[1]),
                'l': ('x', sep_rect[0]),
                'r': ('x', sep_rect[2])}
    frontier = [rect]
    ret_list = []
    while frontier:
        rect_local = frontier.pop()
        temp_rect_lst = []
        for k, v in line_map.items():
            ret = cut_rect_by_line(rect_local, v)
            ret = [i for i in ret.values() if i and list(i) != list(rect_local)]
            temp_rect_lst.extend(ret)
        if not temp_rect_lst:
            ret_list.append(rect_local)
        frontier.extend(temp_rect_lst)
        frontier = list(set(frontier))

    return list(set(ret_list))


class RingEdgeMap:
    OL = 'ol'
    OR = 'or'
    OT = 'ot'
    OB = 'ob'
    OLT = 'olt'
    ORT = 'ort'
    OLB = 'olb'
    ORB = 'orb'
    IL = 'il'
    IR = 'ir'
    IT = 'it'
    IB = 'ib'
    ILT = 'ilt'
    IRT = 'irt'
    ILB = 'ilb'
    IRB = 'irb'
    C = 'c'


def get_rect_section(rect, sep_rect):
    rect_center = (rect[2] + rect[0]) / 2, (rect[3] + rect[1]) / 2
    sep_rect_center = (sep_rect[2] + sep_rect[0]) / 2, (sep_rect[3] + sep_rect[1]) / 2
    top = rect_center[1] > sep_rect[3]
    bottom = rect_center[1] < sep_rect[1]
    left = rect_center[0] < sep_rect[0]
    right = rect_center[0] > sep_rect[2]
    if left and top:
        return RingEdgeMap.OLT
    if left and bottom:
        return RingEdgeMap.OLB
    if right and top:
        return RingEdgeMap.ORT
    if right and bottom:
        return RingEdgeMap.ORB
    if left:
        return RingEdgeMap.OL
    if right:
        return RingEdgeMap.OR
    if top:
        return RingEdgeMap.OT
    if bottom:
        return RingEdgeMap.OB

    return RingEdgeMap.C


if __name__ == '__main__':

    fig, ax = plt.subplots()

    ax.plot([10, 10], [10, 10])
    rect = (0, 0, 100, 100)
    sep_rect = (30, 40, 90, 90)
    ax.add_patch(Rectangle((sep_rect[0], sep_rect[1]), sep_rect[2] - sep_rect[0], sep_rect[3] - sep_rect[1], fill=False, linewidth=1, color="red"))
    ax.add_patch(Rectangle((rect[0], rect[1]), rect[2] - rect[0], rect[3] - rect[1], fill=False, linewidth=1, color='blue'))

    rect_list = cut_rect_by_rect(rect, sep_rect=sep_rect)
    rect_list = list(set(rect_list))
    i = 0
    for rect in rect_list:
        i += 1
        c = randomcolor()
        section_name = get_rect_section(rect, sep_rect)
        ax.add_patch(Rectangle((rect[0], rect[1]), rect[2] - rect[0], rect[3] - rect[1], fill=True, linewidth=1, color=c, alpha=0.1))
        plt.text(x=(rect[2] + rect[0]) // 2, y=(rect[3] + rect[1]) // 2, color=c, s=section_name)

    plt.show()
